View Javadoc

1   // Deflater.java, created Mon Jul  8  4:06:18 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.ClassLib.Common.java.util.zip;
5   
6   /***
7    * Deflater
8    *
9    * @author  John Whaley <jwhaley@alum.mit.edu>
10   * @version $Id: Deflater.java 1451 2004-03-09 06:27:08Z jwhaley $
11   */
12  public class Deflater {
13  
14      private static void initIDs() { }
15      
16    /***
17     * The best and slowest compression level.  This tries to find very
18     * long and distant string repetitions.  
19     */
20    public static final int BEST_COMPRESSION = 9;
21    /***
22     * The worst but fastest compression level.  
23     */
24    public static final int BEST_SPEED = 1;
25    /***
26     * The default compression level.
27     */
28    public static final int DEFAULT_COMPRESSION = -1;
29    /***
30     * This level won't compress at all but output uncompressed blocks.
31     */
32    public static final int NO_COMPRESSION = 0;
33  
34    /***
35     * The default strategy.
36     */
37    public static final int DEFAULT_STRATEGY = 0;
38    /***
39     * This strategy will only allow longer string repetitions.  It is
40     * useful for random data with a small character set.
41     */
42    public static final int FILTERED = 1;
43  
44    /*** 
45     * This strategy will not look for string repetitions at all.  It
46     * only encodes with Huffman trees (which means, that more common
47     * characters get a smaller encoding.  
48     */
49    public static final int HUFFMAN_ONLY = 2;
50  
51    /***
52     * The compression method.  This is the only method supported so far.
53     * There is no need to use this constant at all.
54     */
55    public static final int DEFLATED = 8;
56  
57    /*
58     * The Deflater can do the following state transitions:
59     *
60     * (1) -> INIT_STATE   ----> INIT_FINISHING_STATE ---.
61     *        /  | (2)      (5)                         |
62     *       /   v          (5)                         |
63     *   (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3)
64     *       \   | (3)                 |        ,-------'
65     *        |  |                     | (3)   /
66     *        v  v          (5)        v      v
67     * (1) -> BUSY_STATE   ----> FINISHING_STATE
68     *                                | (6)
69     *                                v
70     *                           FINISHED_STATE
71     *    \_____________________________________/
72     *          | (7)
73     *          v
74     *        CLOSED_STATE
75     *
76     * (1) If we should produce a header we start in INIT_STATE, otherwise
77     *     we start in BUSY_STATE.
78     * (2) A dictionary may be set only when we are in INIT_STATE, then
79     *     we change the state as indicated.
80     * (3) Whether a dictionary is set or not, on the first call of deflate
81     *     we change to BUSY_STATE.
82     * (4) -- intentionally left blank -- :)
83     * (5) FINISHING_STATE is entered, when flush() is called to indicate that
84     *     there is no more INPUT.  There are also states indicating, that
85     *     the header wasn't written yet.
86     * (6) FINISHED_STATE is entered, when everything has been flushed to the
87     *     internal pending output buffer.
88     * (7) At any time (7)
89     * 
90     */
91  
92    private static final int IS_SETDICT              = 0x01;
93    private static final int IS_FLUSHING             = 0x04;
94    private static final int IS_FINISHING            = 0x08;
95    
96    private static final int INIT_STATE              = 0x00;
97    private static final int SETDICT_STATE           = 0x01;
98    private static final int INIT_FINISHING_STATE    = 0x08;
99    private static final int SETDICT_FINISHING_STATE = 0x09;
100   private static final int BUSY_STATE              = 0x10;
101   private static final int FLUSHING_STATE          = 0x14;
102   private static final int FINISHING_STATE         = 0x1c;
103   private static final int FINISHED_STATE          = 0x1e;
104   private static final int CLOSED_STATE            = 0x7f;
105 
106   /*** Compression level. */
107   private int level;
108 
109   /*** should we include a header. */
110   private boolean noHeader;
111 
112   /*** Compression strategy. */
113   private int strategy;
114 
115   /*** The current state. */
116   private int state;
117 
118   /*** The total bytes of output written. */
119   private int totalOut;
120  
121   /*** The pending output. */
122   private DeflaterPending pending;
123 
124   /*** The deflater engine. */
125   private DeflaterEngine engine;
126 
127   /***
128    * Creates a new deflater with default compression level.
129    */
130   public Deflater()
131   {
132     this(DEFAULT_COMPRESSION, false);
133   }
134 
135   /***
136    * Creates a new deflater with given compression level.
137    * @param lvl the compression level, a value between NO_COMPRESSION
138    * and BEST_COMPRESSION, or DEFAULT_COMPRESSION.  
139    * @exception IllegalArgumentException if lvl is out of range.
140    */
141   public Deflater(int lvl)
142   {
143     this(lvl, false);
144   }
145 
146   /***
147    * Creates a new deflater with given compression level.
148    * @param lvl the compression level, a value between NO_COMPRESSION
149    * and BEST_COMPRESSION.  
150    * @param nowrap true, iff we should suppress the deflate header at the
151    * beginning and the adler checksum at the end of the output.  This is
152    * useful for the GZIP format.
153    * @exception IllegalArgumentException if lvl is out of range.
154    */
155   public Deflater(int lvl, boolean nowrap)
156   {
157     if (lvl == DEFAULT_COMPRESSION)
158       lvl = 6;
159     else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION)
160       throw new IllegalArgumentException();
161 
162     pending = new DeflaterPending();
163     engine = new DeflaterEngine(pending);
164     this.noHeader = nowrap;
165     setStrategy(DEFAULT_STRATEGY);
166     setLevel(lvl);
167     reset();
168   }
169 
170   /*** 
171    * Resets the deflater.  The deflater acts afterwards as if it was
172    * just created with the same compression level and strategy as it
173    * had before.  
174    */
175   public void reset() 
176   {
177     state = (noHeader ? BUSY_STATE : INIT_STATE);
178     totalOut = 0;
179     pending.reset();
180     engine.reset();
181   }
182   
183   /***
184    * Frees all objects allocated by the compressor.  There's no
185    * reason to call this, since you can just rely on garbage
186    * collection.  Exists only for compatibility against Sun's JDK,
187    * where the compressor allocates native memory.
188    * If you call any method (even reset) afterwards the behaviour is
189    * <i>undefined</i>.  
190    * @deprecated Just clear all references to deflater instead.
191    */
192   public void end()
193   {
194     engine = null;
195     pending = null;
196     state = CLOSED_STATE;
197   }
198 
199   /*** 
200    * Gets the current adler checksum of the data that was processed so
201    * far.
202    */
203   public int getAdler()
204   {
205     return engine.getAdler();
206   }
207 
208   /*** 
209    * Gets the number of input bytes processed so far.
210    */
211   public int getTotalIn()
212   {
213     return engine.getTotalIn();
214   }
215 
216   /*** 
217    * Gets the number of output bytes so far.
218    */
219   public int getTotalOut()
220   {
221     return totalOut;
222   }
223 
224   /*** 
225    * Finalizes this object.
226    */
227   protected void finalize() throws Throwable
228   {
229     /* Exists solely for compatibility.  We don't have any native state. */
230     super.finalize();
231   }
232 
233   /*** 
234    * Flushes the current input block.  Further calls to deflate() will
235    * produce enough output to inflate everything in the current input
236    * block.  This is not part of Sun's JDK so I have made it package
237    * private.  It is used by DeflaterOutputStream to implement
238    * flush().
239    */
240   void flush() {
241     state |= IS_FLUSHING;
242   }
243 
244   /*** 
245    * Finishes the deflater with the current input block.  It is an error
246    * to give more input after this method was called.  This method must
247    * be called to force all bytes to be flushed.
248    */
249   public void finish() {
250     state |= IS_FLUSHING | IS_FINISHING;
251   }
252 
253   /*** 
254    * Returns true iff the stream was finished and no more output bytes
255    * are available.
256    */
257   public boolean finished()
258   {
259     return state == FINISHED_STATE && pending.isFlushed();
260   }
261 
262   /***
263    * Returns true, if the input buffer is empty.
264    * You should then call setInput(). <br>
265    *
266    * <em>NOTE</em>: This method can also return true when the stream
267    * was finished.  
268    */
269   public boolean needsInput()
270   {
271     return engine.needsInput();
272   }
273 
274   /***
275    * Sets the data which should be compressed next.  This should be only
276    * called when needsInput indicates that more input is needed.
277    * If you call setInput when needsInput() returns false, the
278    * previous input that is still pending will be thrown away.
279    * The given byte array should not be changed, before needsInput() returns
280    * true again.
281    * This call is equivalent to <code>setInput(input, 0, input.length)</code>.
282    * @param input the buffer containing the input data.
283    * @exception IllegalStateException if the buffer was finished() or ended().
284    */
285   public void setInput(byte[] input)
286   {
287     setInput(input, 0, input.length);
288   }
289 
290   /***
291    * Sets the data which should be compressed next.  This should be
292    * only called when needsInput indicates that more input is needed.
293    * The given byte array should not be changed, before needsInput() returns
294    * true again.
295    * @param input the buffer containing the input data.
296    * @param off the start of the data.
297    * @param len the length of the data.  
298    * @exception IllegalStateException if the buffer was finished() or ended()
299    * or if previous input is still pending.
300    */
301   public void setInput(byte[] input, int off, int len)
302   {
303     if ((state & IS_FINISHING) != 0)
304       throw new IllegalStateException("finish()/end() already called");
305     engine.setInput(input, off, len);
306   }
307 
308   /*** 
309    * Sets the compression level.  There is no guarantee of the exact
310    * position of the change, but if you call this when needsInput is
311    * true the change of compression level will occur somewhere near
312    * before the end of the so far given input.  
313    * @param lvl the new compression level.
314    */
315   public void setLevel(int lvl)
316   {
317     if (lvl == DEFAULT_COMPRESSION)
318       lvl = 6;
319     else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION)
320       throw new IllegalArgumentException();
321 
322 
323     if (level != lvl)
324       {
325         level = lvl;
326         engine.setLevel(lvl);
327       }
328   }
329 
330   /*** 
331    * Sets the compression strategy. Strategy is one of
332    * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED.  For the exact
333    * position where the strategy is changed, the same as for
334    * setLevel() applies.
335    * @param stgy the new compression strategy.
336    */
337   public void setStrategy(int stgy)
338   {
339     if (stgy != DEFAULT_STRATEGY && stgy != FILTERED
340         && stgy != HUFFMAN_ONLY)
341       throw new IllegalArgumentException();
342     engine.setStrategy(stgy);
343   }
344 
345   /***
346    * Deflates the current input block to the given array.  It returns 
347    * the number of bytes compressed, or 0 if either 
348    * needsInput() or finished() returns true or length is zero.
349    * @param output the buffer where to write the compressed data.
350    */
351   public int deflate(byte[] output)
352   {
353     return deflate(output, 0, output.length);
354   }
355 
356   /***
357    * Deflates the current input block to the given array.  It returns 
358    * the number of bytes compressed, or 0 if either 
359    * needsInput() or finished() returns true or length is zero.
360    * @param output the buffer where to write the compressed data.
361    * @param offset the offset into the output array.
362    * @param length the maximum number of bytes that may be written.
363    * @exception IllegalStateException if end() was called.
364    * @exception IndexOutOfBoundsException if offset and/or length
365    * don't match the array length.  
366    */
367   public int deflate(byte[] output, int offset, int length)
368   {
369     int origLength = length;
370 
371     if (state == CLOSED_STATE)
372       throw new IllegalStateException("Deflater closed");
373 
374     if (state < BUSY_STATE)
375       {
376         /* output header */
377         int header = (DEFLATED + 
378                       ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
379         int level_flags = (level - 1) >> 1;
380         if (level_flags < 0 || level_flags > 3) 
381           level_flags = 3;
382         header |= level_flags << 6;
383         if ((state & IS_SETDICT) != 0)
384           /* Dictionary was set */
385           header |= DeflaterConstants.PRESET_DICT;
386         header += 31 - (header % 31);
387 
388         pending.writeShortMSB(header);
389         if ((state & IS_SETDICT) != 0)
390           {
391             int chksum = engine.getAdler();
392             engine.resetAdler();
393             pending.writeShortMSB(chksum >> 16);
394             pending.writeShortMSB(chksum & 0xffff);
395           }
396 
397         state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
398       }
399 
400     for (;;)
401       {
402         int count = pending.flush(output, offset, length);
403         offset += count;
404         totalOut += count;
405         length -= count;
406         if (length == 0 || state == FINISHED_STATE)
407           break;
408 
409         if (!engine.deflate((state & IS_FLUSHING) != 0, 
410                             (state & IS_FINISHING) != 0))
411           {
412             if (state == BUSY_STATE)
413               /* We need more input now */
414               return origLength - length;
415             else if (state == FLUSHING_STATE)
416               {
417                 if (level != NO_COMPRESSION)
418                   {
419                     /* We have to supply some lookahead.  8 bit lookahead
420                      * are needed by the zlib inflater, and we must fill 
421                      * the next byte, so that all bits are flushed.
422                      */
423                     int neededbits = 8 + ((-pending.getBitCount()) & 7);
424                     while (neededbits > 0)
425                       {
426                         /* write a static tree block consisting solely of
427                          * an EOF:
428                          */
429                         pending.writeBits(2, 10);
430                         neededbits -= 10;
431                       }
432                   }
433                 state = BUSY_STATE;
434               }
435             else if (state == FINISHING_STATE)
436               {
437                 pending.alignToByte();
438                 /* We have completed the stream */
439                 if (!noHeader)
440                   {
441                     int adler = engine.getAdler();
442                     pending.writeShortMSB(adler >> 16);
443                     pending.writeShortMSB(adler & 0xffff);
444                   }
445                 state = FINISHED_STATE;
446               }
447           }
448       }
449 
450     return origLength - length;
451   }
452 
453   /***
454    * Sets the dictionary which should be used in the deflate process.
455    * This call is equivalent to <code>setDictionary(dict, 0,
456    * dict.length)</code>.  
457    * @param dict the dictionary.  
458    * @exception IllegalStateException if setInput () or deflate ()
459    * were already called or another dictionary was already set.  
460    */
461   public void setDictionary(byte[] dict)
462   {
463     setDictionary(dict, 0, dict.length);
464   }
465 
466   /***
467    * Sets the dictionary which should be used in the deflate process.
468    * The dictionary should be a byte array containing strings that are
469    * likely to occur in the data which should be compressed.  The
470    * dictionary is not stored in the compressed output, only a
471    * checksum.  To decompress the output you need to supply the same
472    * dictionary again.
473    * @param dict the dictionary.
474    * @param offset an offset into the dictionary.
475    * @param length the length of the dictionary.
476    * @exception IllegalStateException if setInput () or deflate () were
477    * already called or another dictionary was already set.
478    */
479   public void setDictionary(byte[] dict, int offset, int length)
480   {
481     if (state != INIT_STATE)
482       throw new IllegalStateException();
483 
484     state = SETDICT_STATE;
485     engine.setDictionary(dict, offset, length);
486   }
487 }